package com.ruoyi.tranShort.service.impl;

import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

import com.ruoyi.common.constant.EditSchedulingTypeConstants;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.tranShort.domain.*;
import com.ruoyi.tranShort.domain.request.SchedulingData;
import com.ruoyi.tranShort.domain.request.SchedulingRequest;
import com.ruoyi.tranShort.domain.response.EditSchedulingRequest;
import com.ruoyi.tranShort.domain.response.SchedulingDataResponse;
import com.ruoyi.tranShort.domain.response.ShortSchedulingResponse;
import com.ruoyi.tranShort.mapper.*;
import com.ruoyi.tranShort.service.IShortSchedulingTaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.tranShort.service.IShortSchedulingService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 排班Service业务层处理
 * 
 * @author ruoyi
 * @date 2021-08-14
 */
@Service
public class ShortSchedulingServiceImpl implements IShortSchedulingService 
{
    @Autowired
    private ShortSchedulingMapper shortSchedulingMapper;
    @Autowired
    private ShortSchedulingDateMapper shortSchedulingDateMapper;
    @Autowired
    private ShortSchedulingDetailMapper shortSchedulingDetailMapper;
    @Autowired
    private ShortSchedulingPersonMapper shortSchedulingPersonMapper;
    @Autowired
    private IShortSchedulingTaskService shortSchedulingTaskService;
    @Autowired
    private ShortSchedulingTaskMapper shortSchedulingTaskMapper;

    /**
     * 查询排班
     * 
     * @param id 排班主键
     * @return 排班
     */
    @Override
    public ShortSchedulingResponse selectShortSchedulingById(Long id)
    {
        ShortSchedulingResponse schedulingResponse = new ShortSchedulingResponse();
        //获取排班信息
        ShortScheduling shortScheduling = shortSchedulingMapper.selectShortSchedulingById(id);
        schedulingResponse.setShortScheduling(shortScheduling);
        List<SchedulingDataResponse> schedulingDataResponseList = new ArrayList<>();
        schedulingResponse.setSchedulingDataList(schedulingDataResponseList);
        //获取七天数据
        List<ShortSchedulingDate> shortSchedulingDateList = shortSchedulingDateMapper.selectShortSchedulingDateBySchedulingId(shortScheduling.getId());
        //循环遍历七天数据进行获取
        for (ShortSchedulingDate shortSchedulingDate : shortSchedulingDateList) {
            Long dayOfWeek = shortSchedulingDate.getDayOfWeek();
            Date dayOfTime = shortSchedulingDate.getDayOfTime();
            Long dateId = shortSchedulingDate.getId();


            //查询出时间段
            List<SchedulingDetailStartAndEnd> schedulingDetailStartAndEndList = shortSchedulingDetailMapper.selectStartAndEndByGroupAndSchedulingDateId(dateId);
            //查询出哨位
            List<ShortSentryPost> shortSentryPostList = shortSchedulingDetailMapper.selectSentryPostIdListByGroupAndSchedulingDateId(dateId);

            SchedulingDataResponse schedulingDataResponse = new SchedulingDataResponse();
            schedulingDataResponse.setSentryPostList(shortSentryPostList);
            //放入集合中
            schedulingDataResponseList.add(schedulingDataResponse);
            schedulingDataResponse.setDayOfWeek(dayOfWeek.intValue());
            schedulingDataResponse.setDateTime(dayOfTime);
            //时间段集合
            List<String> timeQuantum = new ArrayList<>();
            schedulingDataResponse.setTimeQuantum(timeQuantum);
            List<ShortSchedulingDetail> shortSchedulingDetailList = shortSchedulingDetailMapper.selectShortSchedulingDateAndPersonBySchedulingDateId(dateId);

            //进行二维数组数据添加
            List<List<List<ShortPerson>>> dataList = new ArrayList<>();
            schedulingDataResponse.setData(dataList);
            for (SchedulingDetailStartAndEnd schedulingDetailStartAndEnd : schedulingDetailStartAndEndList) {
                String startTimeQuantum = schedulingDetailStartAndEnd.getStartTimeQuantum();
                String endTimeQuantum = schedulingDetailStartAndEnd.getEndTimeQuantum();
                //时间段拼接
                String timeQuantumBuild = startTimeQuantum+"-"+endTimeQuantum;
                timeQuantum.add(timeQuantumBuild);
                List<List<ShortPerson>> shortPersonList = new ArrayList<>();
                //哨位
                for (ShortSentryPost shortSentryPost : shortSentryPostList) {
                    Long id1 = shortSentryPost.getId();
                    //判断
                    for (ShortSchedulingDetail shortSchedulingDetail : shortSchedulingDetailList) {
                        String startTimeQuantum1 = shortSchedulingDetail.getStartTimeQuantum();
                        String endTimeQuantum1 = shortSchedulingDetail.getEndTimeQuantum();
                        Long sentryPostId = shortSchedulingDetail.getSentryPostId();
                        List<ShortPerson> shortPersonList1 = shortSchedulingDetail.getShortPersonList();
                        //获取指定数据，并放入集合中
                        if(startTimeQuantum1.equals(startTimeQuantum) && endTimeQuantum1.equals(endTimeQuantum)&&id1.intValue() == sentryPostId ){
                            //放入数组中
                            shortPersonList.add(shortPersonList1);
                            break;
                        }
                    }
                }
                dataList.add(shortPersonList);
            }
        }
        return schedulingResponse;
    }

    /**
     * 查询排班列表
     * 
     * @param shortScheduling 排班
     * @return 排班
     */
    @Override
    public List<ShortScheduling> selectShortSchedulingList(ShortScheduling shortScheduling)
    {
        return shortSchedulingMapper.selectShortSchedulingList(shortScheduling);
    }

    /**
     * 新增排班
     * 
     * @param shortScheduling 排班
     * @return 结果
     */
    @Override
    public int insertShortScheduling(ShortScheduling shortScheduling)
    {
        shortScheduling.setCreateTime(DateUtils.getNowDate());
        return shortSchedulingMapper.insertShortScheduling(shortScheduling);
    }

    /**
     * 修改排班
     * 
     * @param shortScheduling 排班
     * @return 结果
     */
    @Override
    public int updateShortScheduling(ShortScheduling shortScheduling)
    {
        return shortSchedulingMapper.updateShortScheduling(shortScheduling);
    }

    /**
     * 批量删除排班
     * 
     * @param ids 需要删除的排班主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteShortSchedulingByIds(Long[] ids)
    {
        //删除排班记录
        int i = shortSchedulingMapper.deleteShortSchedulingByIds(ids);
        //查询出排班日期
        Long[] schedulingDateId = shortSchedulingDateMapper.selectShortSchedulingDateIdBySchedulingIds(ids);
        //删除排班日期表
        int i1 = shortSchedulingDateMapper.deleteShortSchedulingDateBySchedulingIds(ids);
        //查询出排班详情记录
        Long[] detailIds = shortSchedulingDetailMapper.selectShortSchedulingDetailIdBySchedulingDateId(schedulingDateId);
        //删除排班详情表
        int i2 = shortSchedulingDetailMapper.deleteShortSchedulingDetailBySchedulingDateId(schedulingDateId);

        //删除排班人员
        int i3 = shortSchedulingPersonMapper.deleteShortSchedulingPersonBySchedulingDetailIds(detailIds);

        //删除任务列表
        int i4 = shortSchedulingTaskMapper.deleteShortSchedulingTaskBySchedulingId(ids);
        return i4;
    }

    /**
     * 删除排班信息
     * 
     * @param id 排班主键
     * @return 结果
     */
    @Override
    public int deleteShortSchedulingById(Long id)
    {
        return shortSchedulingMapper.deleteShortSchedulingById(id);
    }

    /**
     * 新增排班
     * @param schedulingRequest
     * @return
     */
    @Transactional
    @Override
    public AjaxResult save(SchedulingRequest schedulingRequest) {
        ShortScheduling shortScheduling = schedulingRequest.getShortScheduling();
        //排班开始时间，是否存在重复
        Date schedulingStartTime = shortScheduling.getSchedulingStartTime();
        //判断时间是否为周一
        Instant instant = schedulingStartTime.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
        int dayOfWeekValue = localDateTime.getDayOfWeek().getValue();
        if(dayOfWeekValue != 1){
            throw new CustomException("开始时间只能为周一");
        }
        //根据时间查询数据库
        ShortScheduling shortScheduling1 = new ShortScheduling();
        shortScheduling1.setSchedulingStartTime(schedulingStartTime);
        List<ShortScheduling> shortSchedulingList = shortSchedulingMapper.selectShortSchedulingList(shortScheduling1);
        if(shortSchedulingList !=null && shortSchedulingList.size()>0){
            throw new CustomException("排班已存在", HttpStatus.BAD_REQUEST);
        }
        List<SchedulingData> schedulingDataList = schedulingRequest.getSchedulingDataList();
        //保存排班表
        shortScheduling.setCreateTime(DateUtils.getNowDate());
        int i = shortSchedulingMapper.insertShortScheduling(shortScheduling);
        //保存排班日期表
        for (SchedulingData schedulingData : schedulingDataList) {
            //周几
            Integer dayOfWeek = schedulingData.getDayOfWeek();
            List<String> timeQuantum = schedulingData.getTimeQuantum();
            List<Long> sentryPost = schedulingData.getSentryPost();
            //人员数据
            List<List<Long>> dataList = schedulingData.getData();

            //当天时间
            Date dateTime = schedulingData.getDateTime();
            ShortSchedulingDate shortSchedulingDate = new ShortSchedulingDate();
            shortSchedulingDate.setSchedulingId(shortScheduling.getId());
            shortSchedulingDate.setDayOfTime(dateTime);
            shortSchedulingDate.setDayOfWeek(dayOfWeek.longValue());
            shortSchedulingDate.setCreateTime(DateUtils.getNowDate());
            int i1 = shortSchedulingDateMapper.insertShortSchedulingDate(shortSchedulingDate);

            //保存排班详细表
            for (int j =0;j<timeQuantum.size();j++) {
                String[] timeSplitArray = timeQuantum.get(j).split("-");
                //添加排班任务
                shortSchedulingTaskService.addTask(shortSchedulingDate.getId(),timeSplitArray[0],timeSplitArray[1],dateTime,shortScheduling.getId());
                for (int k =0;k<sentryPost.size();k++) {
                    ShortSchedulingDetail shortSchedulingDetail = new ShortSchedulingDetail();
                    shortSchedulingDetail.setSchedulingDateId(shortSchedulingDate.getId());
                    shortSchedulingDetail.setStartTimeQuantum(timeSplitArray[0]);
                    shortSchedulingDetail.setEndTimeQuantum(timeSplitArray[1]);
                    shortSchedulingDetail.setSentryPostId(sentryPost.get(k));
                    shortSchedulingDetail.setCreateTime(DateUtils.getNowDate());
                    int i2 = shortSchedulingDetailMapper.insertShortSchedulingDetail(shortSchedulingDetail);
                    //保存排班人员
                    ShortSchedulingPerson shortSchedulingPerson = new ShortSchedulingPerson();
                    Long personId = dataList.get(j).get(k);
                    shortSchedulingPerson.setPersonId(personId);
                    Long id = shortSchedulingDetail.getId();
                    shortSchedulingPerson.setSchedulingDetailId(id);
                    shortSchedulingPerson.setCreateTime(DateUtils.getNowDate());
                    int i3 = shortSchedulingPersonMapper.insertShortSchedulingPerson(shortSchedulingPerson);

                }

            }

        }

        return AjaxResult.success();
    }

    /**
     * 获取当天排班
     * @return
     */
    @Override
    public SchedulingDataResponse getSchedulingDay() {
        //获取当天的日期数据
        ShortSchedulingDate shortSchedulingDate = shortSchedulingDateMapper.selectShortSchedulingDateByDayOfTime();
        if(shortSchedulingDate == null){
            throw new CustomException("当天没有数据",HttpStatus.DATA_NULL);
        }
        Long dayOfWeek = shortSchedulingDate.getDayOfWeek();
        Date dayOfTime = shortSchedulingDate.getDayOfTime();
        Long dateId = shortSchedulingDate.getId();
        //查询出时间段
        List<SchedulingDetailStartAndEnd> schedulingDetailStartAndEndList = shortSchedulingDetailMapper.selectStartAndEndByGroupAndSchedulingDateId(dateId);
        //查询出哨位
        List<ShortSentryPost> shortSentryPostList = shortSchedulingDetailMapper.selectSentryPostIdListByGroupAndSchedulingDateId(dateId);

        SchedulingDataResponse schedulingDataResponse = new SchedulingDataResponse();
        schedulingDataResponse.setSchedulingDateId(dateId);
        schedulingDataResponse.setSentryPostList(shortSentryPostList);
        //放入集合中

        schedulingDataResponse.setDayOfWeek(dayOfWeek.intValue());
        schedulingDataResponse.setDateTime(dayOfTime);
        //时间段集合
        List<String> timeQuantum = new ArrayList<>();
        schedulingDataResponse.setTimeQuantum(timeQuantum);
        List<ShortSchedulingDetail> shortSchedulingDetailList = shortSchedulingDetailMapper.selectShortSchedulingDateAndPersonBySchedulingDateId(dateId);

        //进行二维数组数据添加
        List<List<List<ShortPerson>>> dataList = new ArrayList<>();
        schedulingDataResponse.setData(dataList);
        for (SchedulingDetailStartAndEnd schedulingDetailStartAndEnd : schedulingDetailStartAndEndList) {
            String startTimeQuantum = schedulingDetailStartAndEnd.getStartTimeQuantum();
            String endTimeQuantum = schedulingDetailStartAndEnd.getEndTimeQuantum();
            //时间段拼接
            String timeQuantumBuild = startTimeQuantum+"-"+endTimeQuantum;
            timeQuantum.add(timeQuantumBuild);
            List<List<ShortPerson>> shortPersonList = new ArrayList<>();
            //哨位
            for (ShortSentryPost shortSentryPost : shortSentryPostList) {
                Long id1 = shortSentryPost.getId();
                //判断
                for (ShortSchedulingDetail shortSchedulingDetail : shortSchedulingDetailList) {
                    String startTimeQuantum1 = shortSchedulingDetail.getStartTimeQuantum();
                    String endTimeQuantum1 = shortSchedulingDetail.getEndTimeQuantum();
                    Long sentryPostId = shortSchedulingDetail.getSentryPostId();
                    List<ShortPerson> shortPersonList1 = shortSchedulingDetail.getShortPersonList();
                    //获取指定数据，并放入集合中
                    if(startTimeQuantum1.equals(startTimeQuantum) && endTimeQuantum1.equals( endTimeQuantum)&&id1.intValue() == sentryPostId ){
                        //放入数组中
                        shortPersonList.add(shortPersonList1);
                        break;
                    }
                }
            }
            dataList.add(shortPersonList);
        }
        return schedulingDataResponse;
    }

    /**
     * 修改排班
     * @param editSchedulingRequest
     * @return
     */
    @Transactional
    @Override
    public int editScheduling(EditSchedulingRequest editSchedulingRequest) {
        Long schedulingDateId = editSchedulingRequest.getSchedulingDateId();

        if(schedulingDateId == null || StringUtils.isEmpty(editSchedulingRequest.getType())){
            throw new CustomException("参数错误",HttpStatus.BAD_REQUEST);
        }
        //判断类型
        switch (editSchedulingRequest.getType()){
            case EditSchedulingTypeConstants.ADD_TIME:
                //参数校验
                if(StringUtils.isEmpty(editSchedulingRequest.getTimeQuantum())){
                    throw new CustomException("参数错误",HttpStatus.BAD_REQUEST);
                }
                if(editSchedulingRequest.getSentryPostIdList() == null || editSchedulingRequest.getSentryPostIdList().size()<=0){
                    throw new CustomException("参数错误",HttpStatus.BAD_REQUEST);
                }
                //添加时间
                this.addTime(schedulingDateId,editSchedulingRequest.getTimeQuantum(),editSchedulingRequest.getSentryPostIdList());

                break;
            case EditSchedulingTypeConstants.DELETE_TIME:
                //删除时间
                if(editSchedulingRequest.getSentryPostIdList() == null || editSchedulingRequest.getSentryPostIdList().size()<=0){
                    throw new CustomException("参数错误",HttpStatus.BAD_REQUEST);
                }
                this.deleteTime(schedulingDateId,editSchedulingRequest.getTimeQuantum(),editSchedulingRequest.getSentryPostIdList());
                break;

            case EditSchedulingTypeConstants.EDIT_TIME:
                //编辑时间
                if(StringUtils.isEmpty(editSchedulingRequest.getOldTimeQuantum()) || StringUtils.isEmpty(editSchedulingRequest.getNewTimeQuantum())){
                    throw new CustomException("参数错误",HttpStatus.BAD_REQUEST);
                }
                this.editTime(schedulingDateId,editSchedulingRequest.getOldTimeQuantum(),editSchedulingRequest.getNewTimeQuantum());
                break;
            case EditSchedulingTypeConstants.EDIT_PERSON:
                //编辑人员
                if(StringUtils.isEmpty(editSchedulingRequest.getTimeQuantum()) || editSchedulingRequest.getSentryPostId() == null || editSchedulingRequest.getPersonData() == null || editSchedulingRequest.getPersonData().size()<=0){
                    throw new CustomException("参数错误",HttpStatus.BAD_REQUEST);
                }
                this.editPerson(schedulingDateId,editSchedulingRequest.getTimeQuantum(),editSchedulingRequest.getSentryPostId(),editSchedulingRequest.getPersonData());
                break;
            default:
                break;
        }
        return 1;
    }

    /**
     * 添加时间
     * @param schedulingDateId
     * @param timeQuantum
     * @return
     */
    private int addTime(Long schedulingDateId,String timeQuantum,List<Long> sentryPostIdList){

        ShortSchedulingDetail shortSchedulingDetail = new ShortSchedulingDetail();

        shortSchedulingDetail.setSchedulingDateId(schedulingDateId);
        String[] split = timeQuantum.split("-");
        shortSchedulingDetail.setStartTimeQuantum(split[0]);
        shortSchedulingDetail.setEndTimeQuantum(split[1]);
        shortSchedulingDetail.setCreateTime(DateUtils.getNowDate());
        for (Long sentryPost : sentryPostIdList) {
            shortSchedulingDetail.setSentryPostId(sentryPost);
            shortSchedulingDetailMapper.insertShortSchedulingDetail(shortSchedulingDetail);
        }
        //查询出日期排班
        ShortSchedulingDate shortSchedulingDate = shortSchedulingDateMapper.selectShortSchedulingDateById(schedulingDateId);
        //添加任务
        int i = shortSchedulingTaskService.addTask(schedulingDateId, split[0], split[1], shortSchedulingDate.getDayOfTime(), shortSchedulingDate.getSchedulingId());
        return i;
    }

    /**
     * 删除时间
     * @param schedulingDateId
     * @param timeQuantum
     * @param sentryPostIdList
     * @return
     */
    private int deleteTime(Long schedulingDateId,String timeQuantum,List<Long> sentryPostIdList){
        ShortSchedulingDetail shortSchedulingDetail = new ShortSchedulingDetail();
        shortSchedulingDetail.setSchedulingDateId(schedulingDateId);
        String[] split = timeQuantum.split("-");
        shortSchedulingDetail.setStartTimeQuantum(split[0]);
        shortSchedulingDetail.setEndTimeQuantum(split[1]);
        Long[] longs = shortSchedulingDetailMapper.selectShortSchedulingDateBySchedulingDateIdAndTime(shortSchedulingDetail);
        for (Long sentryPost : sentryPostIdList) {
            shortSchedulingDetail.setSentryPostId(sentryPost);
            //查询出详情信息

            //删除排班详情表
            int i = shortSchedulingDetailMapper.deleteSHortSchedulingDetailBySchedulingDate(shortSchedulingDetail);

        }
        //删除人员关联
        int i = shortSchedulingPersonMapper.deleteShortSchedulingPersonBySchedulingDetailIds(longs);
        //查询出日期排班
        ShortSchedulingDate shortSchedulingDate = shortSchedulingDateMapper.selectShortSchedulingDateById(schedulingDateId);
        //删除任务
        int i1 = shortSchedulingTaskService.deleteTask(schedulingDateId, split[0], split[1], shortSchedulingDate.getDayOfTime(), shortSchedulingDate.getSchedulingId());
        return i1;
    }

    /**
     * 修改时间
     * @param schedulingDateId
     * @param oldTimeQuantum
     * @param newTimeQuantum
     * @return
     */
    private int editTime(Long schedulingDateId,String oldTimeQuantum,String newTimeQuantum){
        String[] oldSplit = oldTimeQuantum.split("-");
        String[] newSplit = newTimeQuantum.split("-");
        Map<String,Object> map = new HashMap<>();
        map.put("schedulingDateId",schedulingDateId);
        map.put("oldStartTimeQuantum",oldSplit[0]);
        map.put("oldEndTimeQuantum",oldSplit[1]);
        map.put("startTimeQuantum",newSplit[0]);
        map.put("endTimeQuantum",newSplit[1]);
        int i = shortSchedulingDetailMapper.updateShortSchedulingDetailByTimeAndDateId(map);
        //修改任务时间
        //查询出日期排班
        ShortSchedulingDate shortSchedulingDate = shortSchedulingDateMapper.selectShortSchedulingDateById(schedulingDateId);
        shortSchedulingTaskService.updateTask(schedulingDateId, oldTimeQuantum, newTimeQuantum, shortSchedulingDate.getDayOfTime(), shortSchedulingDate.getSchedulingId());
        return i;
    }

    /**
     * 修改人员
     * @param schedulingDateId
     * @param timeQuantum
     * @param personData
     * @return
     */
    private int editPerson(Long schedulingDateId,String timeQuantum,Long sentryPostId,List<Long> personData){
        ShortSchedulingDetail shortSchedulingDetail = new ShortSchedulingDetail();
        shortSchedulingDetail.setSchedulingDateId(schedulingDateId);
        String[] split = timeQuantum.split("-");
        shortSchedulingDetail.setStartTimeQuantum(split[0]);
        shortSchedulingDetail.setEndTimeQuantum(split[1]);
        shortSchedulingDetail.setSentryPostId(sentryPostId);
        ShortSchedulingDetail shortSchedulingDetail1 = shortSchedulingDetailMapper.selectShortSchedulingDateOneBySchedulingDateIdAndTime(shortSchedulingDetail);
        if(shortSchedulingDetail1 != null){
            Long id = shortSchedulingDetail1.getId();
            //根据id删除人员关联
            Long[] ids = {
                    id
            };
            int i = shortSchedulingPersonMapper.deleteShortSchedulingPersonBySchedulingDetailIds(ids);
            //添加人员
            for (Long personDatum : personData) {
                ShortSchedulingPerson shortSchedulingPerson = new ShortSchedulingPerson();
                shortSchedulingPerson.setCreateTime(DateUtils.getNowDate());
                shortSchedulingPerson.setSchedulingDetailId(id);
                shortSchedulingPerson.setPersonId(personDatum);
                int i1 = shortSchedulingPersonMapper.insertShortSchedulingPerson(shortSchedulingPerson);
            }

        }
        return 1;
    }
}
